package com.idea.relax.log.listener;

import com.idea.relax.log.constant.ApiLogConstant;
import com.idea.relax.log.model.ApiLogModel;
import com.idea.relax.log.publisher.ILogPublisher;
import com.idea.relax.log.service.IApiLogService;
import com.idea.relax.log.service.IRelaxLogService;
import com.idea.relax.log.support.CallbackMessage;
import com.idea.relax.log.support.AppInfoProvider;
import com.idea.relax.log.support.spel.EvaluationContextRootObject;
import com.idea.relax.log.support.spel.RelaxExpressionParser;
import com.idea.relax.log.support.utils.Func;
import com.idea.relax.log.api.callback.RelaxFailureCallbackHandler;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.expression.AnnotatedElementKey;
import org.springframework.expression.EvaluationContext;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

/**
 * @className: ApiLogWorker
 * @description:
 * @author: salad
 * @date: 2023/1/6
 **/
@Slf4j
@AllArgsConstructor
public class ApiLogWorker implements Runnable {

    private final ILogPublisher.Wrapper<Map<String, Object>> wrapper;

    private final RelaxExpressionParser expressionParser;

    private final IApiLogService apiLogService;

    private final IRelaxLogService relaxLogService;

    private final RelaxFailureCallbackHandler failureCallbackHandler;

    @Override
    public void run() {
        try {
            //存储操作日志
            saveApiLog();
        } catch (Exception e) {
            Map<String, Object> data = new HashMap<>(16);
            data.put("source", "ApiLog");
            data.put(ApiLogConstant.API_LOG_MODEL, wrapper.getValue().get(ApiLogConstant.API_LOG_MODEL));
            CallbackMessage message = new CallbackMessage(Thread.currentThread(), e, data);
            failureCallbackHandler.onException(message);
        }

    }

    private void saveApiLog() {
        Map<String, Object> values = wrapper.getValue();
        ApiLogModel model = (ApiLogModel) values.get(ApiLogConstant.API_LOG_MODEL);
        EvaluationContextRootObject rootObject = (EvaluationContextRootObject) values.get(ApiLogConstant.ROOT_OBJECT);
        String description = model.getDescription();
        if (Func.isNotBlank(description)) {
            EvaluationContext context = expressionParser.createContext(rootObject, true);
            AnnotatedElementKey elementKey = new AnnotatedElementKey(rootObject.getMethod(), rootObject.getTargetClass());
            String des = expressionParser.evalAsText(description, elementKey, context);
            model.setDescription(des);
        }
        //向实体类中增加额外的信息
        AppInfoProvider.appendServerInfo(model);
        Optional.ofNullable(apiLogService)
                .ifPresent(service -> service.saveApiLog(model));
        Optional.ofNullable(relaxLogService)
                .ifPresent(service -> service.saveApiLog(model));
    }


}
